package com.alm.handle.service.impl;

import com.alm.common.core.domain.AjaxResult;
import com.alm.common.enums.OnlineStatusEnum;
import com.alm.common.enums.WorkStatusEnum;
import com.alm.common.exception.ServiceException;
import com.alm.common.utils.SecurityUtils;
import com.alm.handle.core.domain.entity.AlmDevGroup;
import com.alm.handle.core.domain.entity.SysDevInfo;
import com.alm.handle.core.domain.entity.rq.DevGroupEditRq;
import com.alm.handle.core.domain.entity.rq.DevGroupListRq;
import com.alm.handle.core.domain.entity.rq.DevGroupAddRq;
import com.alm.handle.core.domain.entity.vo.*;
import com.alm.handle.mapper.AlmDevGroupMapper;
import com.alm.handle.mapper.SysDevInfoMapper;
import com.alm.handle.service.AlmDevGroupService;
import com.alm.common.utils.TimeUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 设备分组信息表 服务实现类
 * </p>
 *
 * @author ywy
 * @since 2024-06-12
 */
@Service
public class AlmDevGroupServiceImpl extends ServiceImpl<AlmDevGroupMapper, AlmDevGroup> implements AlmDevGroupService {

    @Resource
    private AlmDevGroupMapper almDevGroupMapper;

    @Resource
    private SysDevInfoMapper devInfoMapper;

    /**
     * 分组列表
     * @param rq
     * @return
     */
    @Override
    public AjaxResult getDevGroupList(DevGroupListRq rq) {
        Long userId = SecurityUtils.getUserId();
        if(userId == null) {
            throw new ServiceException("无法获取用户信息");
        }
        // 查询
        LambdaQueryWrapper<AlmDevGroup> queryWrapper = new LambdaQueryWrapper<AlmDevGroup>().eq(AlmDevGroup::getUserId, userId)
                .orderByAsc(AlmDevGroup::getSort);
        if(StringUtils.isNotBlank(rq.getGroupName())){
            queryWrapper.like(AlmDevGroup::getGroupName, rq.getGroupName());
        }
        List<AlmDevGroup> almDevGroups = almDevGroupMapper.selectList(queryWrapper);
        // 转换
        List<DevGroupVO> resList = almDevGroups.stream().map(obj -> {
            DevGroupVO vo = new DevGroupVO();
            BeanUtils.copyProperties(obj, vo);

            return vo;
        }).collect(Collectors.toList());

        List<Integer> groupIds = resList.stream().map(DevGroupVO::getId).collect(Collectors.toList());
        if(groupIds != null && groupIds.size() > 0) {
            // 获取设备分组下设备数量
            List<DevInfoCountVO> countVOList = devInfoMapper.getCountByDevGroupIds(groupIds);
            resList.forEach(e ->{
                DevInfoCountVO countVO = countVOList.stream().filter(vo -> e.getId().equals(vo.getDevGroupId())).findFirst().orElse(null);
                if(countVO == null) {
                    e.setDevInfoCount(0);
                }else {
                    e.setDevInfoCount(countVO.getDevCount());
                }
            });
        }


        return AjaxResult.success(resList);
    }

    /**
     * 更新分组
     * @param rq
     * @return
     */
    @Override
    public int editDevGroup(DevGroupEditRq rq) {
        Long userId = SecurityUtils.getUserId();
        // 根据组名查询, 排除自己的
        AlmDevGroup devGroup = almDevGroupMapper.selectOne(new QueryWrapper<AlmDevGroup>().lambda()
                .eq(AlmDevGroup::getGroupName, rq.getGroupName())
                .eq(AlmDevGroup::getUserId, userId)
                .ne(AlmDevGroup::getId, rq.getId()));
        if(devGroup != null) {
            throw new ServiceException("存在相同的组名不可更新");
        }

        AlmDevGroup entity = new AlmDevGroup();
        BeanUtils.copyProperties(rq, entity);
        return almDevGroupMapper.updateById(entity);
    }

    /**
     * 新增分组
     * @param rq
     * @return
     */
    @Override
    public int addDevGroup(DevGroupAddRq rq) {
        Long userId = SecurityUtils.getUserId();
        // 根据组名查询
        AlmDevGroup devGroup = almDevGroupMapper.selectOne(new QueryWrapper<AlmDevGroup>().lambda()
                .eq(AlmDevGroup::getGroupName, rq.getGroupName())
                .eq(AlmDevGroup::getUserId, userId));
        if(devGroup != null) {
            throw new ServiceException("存在相同的组名不可新增");
        }

        // 插入
        AlmDevGroup entity = new AlmDevGroup();
        entity.setGroupName(rq.getGroupName());
        entity.setCreatedBy(SecurityUtils.getUsername());
        entity.setUpdateBy(SecurityUtils.getUsername());
        entity.setUserId(userId);
        entity.setSort(rq.getSort());

        return almDevGroupMapper.insert(entity);
    }

    /**
     * 分组信息详情
     * @param devGroupId
     * @return
     */
    @Override
    public DevGroupDetailVO detail(Integer devGroupId) {
        Long userId = SecurityUtils.getUserId();
        AlmDevGroup devGroup = almDevGroupMapper.selectOne(new QueryWrapper<AlmDevGroup>().lambda()
                .eq(AlmDevGroup::getId, devGroupId).eq(AlmDevGroup::getUserId, userId));

        DevGroupDetailVO vo  = new DevGroupDetailVO();
        BeanUtils.copyProperties(devGroup, vo);

        return vo;
    }

    @Override
    public int del(Integer devGroupId) {
        // 分组下存在关联设备，不可删除
        Integer devInfoCount = devInfoMapper.selectCount(new QueryWrapper<SysDevInfo>().lambda()
                .eq(SysDevInfo::getDevGroupId, devGroupId));
        if(devInfoCount > 0) {
            throw new ServiceException("该设备分组下存在设备，不可删除");
        }

        Long userId = SecurityUtils.getUserId();
        int row = almDevGroupMapper.delete(new QueryWrapper<AlmDevGroup>().lambda()
                .eq(AlmDevGroup::getUserId, userId).eq(AlmDevGroup::getId, devGroupId));
        return row;
    }

    @Override
    public List<DevGroupDictVO> getDict() {
        Long userId = SecurityUtils.getUserId();
        List<AlmDevGroup> groupList = almDevGroupMapper.selectList(new QueryWrapper<AlmDevGroup>().lambda()
                .eq(AlmDevGroup::getUserId, userId));

        List<DevGroupDictVO> dictVOList = groupList.stream().map(obj -> {
            DevGroupDictVO vo = new DevGroupDictVO();
            vo.setDevGroupId(obj.getId());
            vo.setDevGroupName(obj.getGroupName());
            return vo;
        }).collect(Collectors.toList());

        return dictVOList;
    }

    @Override
    public List<DevInfoListVO> getDevInfoByGroupId(Integer devGroupId) {
        List<DevInfoListVO> list = devInfoMapper.getDevInfoByGroupId(devGroupId);
        list.forEach(e -> {
            e.setAddTimeStr(TimeUtil.format(e.getAddTime()));
            e.setOnlineStatusStr(OnlineStatusEnum.getByCode(e.getOnlineStatus()));
            // 设备在线且工作中，才算工作
            if(e.getOnlineStatus().equals(OnlineStatusEnum.ONLINE.getCode()) && e.getWorkStatus().equals(WorkStatusEnum.WORKING.getCode())) {
                e.setWorkStatusStr(WorkStatusEnum.WORKING.getValue());
            }else {
                e.setWorkStatusStr(WorkStatusEnum.NOT_WORK.getValue());
            }
        });

        return list;
    }
}
